package org.imlinker.plugin.say;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

public class FanfouBot extends Robot {

	final String FRIENDS_TIMELINE = "http://api.fanfou.com/statuses/friends_timeline.rss";
	final String UPDATE_URL = "http://api.fanfou.com/statuses/update.xml";
	final String USER_TIMELINE = "http://api.fanfou.com/statuses/user_timeline.rss";
	final String ADDBUDDY_URL = " http://api.fanfou.com/friendships/create.xml";

	public FanfouBot(String username, String password) {
		this.username = username;
		this.password = password;
	}

	@Override
	public ArrayList<String> getMessages() {
		if (client == null) {
			return null;
		}

		GetMethod get = new GetMethod(FRIENDS_TIMELINE);

		get.setDoAuthentication(true);
		int status = 401;
		try {
			status = client.executeMethod(get);

			if (status == 200) {

				ArrayList<String> messages = new ArrayList<String>();

				SAXBuilder builder = new SAXBuilder();
				Document doc = builder.build(get.getResponseBodyAsStream());
				Element root = (Element) doc.getRootElement().getChildren()
						.get(0);

				@SuppressWarnings("unchecked")
				List list = root.getChildren();
				Element e;
				for (int i = 0; i < list.size(); i++) {
					e = (Element) list.get(i);
					if (e.getName() != "item") {
						continue;
					}
					messages.add(e.getChildText("title"));
				}

				Collections.reverse(messages);
				return messages;
			}

		} catch (HttpException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (JDOMException e) {
			e.printStackTrace();
		} finally {
			get.releaseConnection();
		}

		return new ArrayList<String>();
	}

	@Override
	public void sendMessage(String message) {
		if (client == null) {
			return;
		}

		PostMethod postMethod = new PostMethod(UPDATE_URL);
		postMethod.addRequestHeader("Content-type",
				"application/x-www-form-urlencoded; charset=UTF-8");
		NameValuePair[] data = { new NameValuePair("status", message) };
		postMethod.setRequestBody(data);
		int statusCode;
		try {
			statusCode = client.executeMethod(postMethod);
			if (statusCode == 200) {
				System.out.println("done");
			}
		} catch (HttpException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			postMethod.releaseConnection();
		}

	}

	@Override
	public void addBuddy(String user) {
		System.out.println("start to add buddy:" + user);

		PostMethod postMethod = new PostMethod(UPDATE_URL);
		postMethod.addRequestHeader("Content-type",
				"application/x-www-form-urlencoded; charset=UTF-8");
		NameValuePair[] data = { new NameValuePair("id", user) };
		postMethod.setRequestBody(data);
		int statusCode;
		try {
			statusCode = client.executeMethod(postMethod);
			if (statusCode == 200) {
				System.out.println("add buddy " + user + " done1");
				System.out.println(postMethod.getResponseBody());
				BufferedReader br = new BufferedReader(new InputStreamReader(
						postMethod.getResponseBodyAsStream()));
				String line;
				while((line=br.readLine())!=null){
					System.out.println(line);
				}
			}
		} catch (HttpException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			postMethod.releaseConnection();
		}

	}

	@Override
	public void removeBuddy(String user) {

	}

	@Override
	public boolean initial() {
		client = new HttpClient();

		client.getState().setCredentials(
				new AuthScope("api.fanfou.com", 80, AuthScope.ANY_REALM),
				new UsernamePasswordCredentials(username, password));

		client.getParams().setAuthenticationPreemptive(true);
		GetMethod get = new GetMethod(USER_TIMELINE);

		get.setDoAuthentication(true);
		int status = 401;
		try {
			status = client.executeMethod(get);
		} catch (HttpException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			get.releaseConnection();
		}

		if (status != 200) {
			client = null;
			return false;
		}

		return true;
	}

	@SuppressWarnings("unchecked")
	public static ArrayList<String> getFriendListByUser(String user) {
		String friendsUrl = "http://api.fanfou.com/users/friends.xml?id=";

		// String html = GetUrlContent.getByUrl(friendsUrl + user);
		// System.out.println(html);

		ArrayList<String> friends = new ArrayList<String>();
		try {
			SAXBuilder builder = new SAXBuilder();
			Document document;
			document = builder.build(new URL(friendsUrl + user));

			List<Element> children = document.getRootElement().getChildren();
			for (Element e : children) {
				if (e.getName() == "user") {
					friends.add(e.getChildText("id"));
				}
			}
		} catch (JDOMException e) {
		} catch (IOException e) {
		}

		return friends;
	}

	public static ArrayList<String> getRecommandList(String user) {
		ArrayList<String> friends = FanfouBot.getFriendListByUser(user);
		HashMap<String, Integer> recommandMap = new HashMap<String, Integer>();

		Integer i;
		for (String name : friends) {
			ArrayList<String> tempList = FanfouBot.getFriendListByUser(name);
			for (String tempName : tempList) {
				if ((i = recommandMap.get(tempName)) != null) {
					recommandMap.put(tempName, i + 1);
				} else {
					recommandMap.put(tempName, 1);
				}
			}
		}

		ArrayList<String> recommandList = new ArrayList<String>();
		String high = null;
		while (!recommandMap.isEmpty()) {
			Set<String> names = recommandMap.keySet();
			high = null;
			Iterator<String> iter = names.iterator();
			while (iter.hasNext()) {
				String name = iter.next();
				if (high == null) {
					high = name;
				} else {
					if (recommandMap.get(high) < recommandMap.get(name)) {
						high = name;
					}
				}
			}

			recommandList.add(high);
			recommandMap.remove(high);
		}

		return recommandList;
	}

	private String username;

	private String password;

	private HttpClient client = null;

}
